

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.Insets;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class FullScreenDemo {
    public static void main(String[] args) {
        FullScreenDemo demo = new FullScreenDemo();
        demo.run();
    }

    public FullScreenDemo() {}

    public void run() {
        final JFrame jframe = new JFrame();
        jframe.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent ev) {
                System.exit(0);
            }
        });

        JButton exitButton = new JButton("退出");
        JButton maxButton = new JButton("最大化显示");
        JButton fullButton = new JButton("全屏显示");

        MaxscreenAction maxAction = new MaxscreenAction(jframe);
        FullscreenAction fullAction = new FullscreenAction(jframe);

        exitButton.addActionListener(new ExitAction());
        maxButton.addActionListener(maxAction);
        fullButton.addActionListener(fullAction);

        jframe.add(maxButton);
        jframe.add(fullButton);
        jframe.add(exitButton);

        jframe.setLayout(new FlowLayout());
        jframe.setSize(400, 300);

        // 显示相关信息
        // 屏幕（screen），即全部显示器显示区域的集合，扩展显示时，为主屏+全部扩展屏的拼接总和。
        // 显示器/监视器（monitor），即真正显示画面的设备，对应实际的物理设备。
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice[] gds = ge.getScreenDevices();
        GraphicsDevice dgd = ge.getDefaultScreenDevice();
        // 获取显示器数量
        System.out.println("Monitor Count: " + gds.length);
        // 获取默认显示器
        System.out.println("Default Monitor: " + dgd.toString());
        // 获取默认显示模式（分辨率@刷新率）
        System.out.println("Default Model: " + dgd.getDisplayMode());
        System.out.println("==== Monitors ============================================================");
        // 获取每个显示器的信息
        for(GraphicsDevice gd : gds) {
            System.out.println("Monitor: " + gd.toString());                                // 打印显示设备
            System.out.println("  Model: " + gd.getDisplayMode());                          // 打印显示器显示模式
            System.out.println("  Support Fullscreen: " + gd.isFullScreenSupported());      // 打印是否支持全屏模式

            GraphicsConfiguration gc = gd.getDefaultConfiguration();
            System.out.println("  Configuration: " + gc.toString());                        // 打印显示设备默认配置
            System.out.println("      Rectangle: " + gc.getBounds());                       // 打印显示设备显示区域信息（坐标+大小）
            if (gds.length > 1) {
                System.out.println("");
            }
        }
        System.out.println("==========================================================================");

        Rectangle maxsize = ge.getMaximumWindowBounds();
        // 获取屏幕最大尺寸
        System.out.println("Maximum Screen Size: " + maxsize);

        Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(ge.getDefaultScreenDevice().getDefaultConfiguration());
        // 获取屏幕可显示区域偏移量，比如任务栏占用宽度等，有些显示系统能提供，有些不能，使用前请判断。
        System.out.println("Screen Insets: " + insets);
        
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        // 获取屏幕大小
        System.out.println("Screen Size: " + screenSize.width + "x" + screenSize.height);

        // 显示在屏幕中间
        Point screenCenter = ge.getCenterPoint();
        jframe.setLocation(screenCenter.x - jframe.getWidth() / 2, screenCenter.y - jframe.getHeight() / 2);

        // 默认最大化
        maxAction.actionPerformed(null);

        jframe.setVisible(true);
    }

    public class ExitAction implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent evt) {
            System.exit(1);
        }
    }

    public class ExitFullscreen implements ActionListener {
        JFrame mainframe;
        public ExitFullscreen(JFrame jframe) {
            this.mainframe = jframe;
        }
        @Override
        public void actionPerformed(ActionEvent evt) {
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice gd = ge.getDefaultScreenDevice();
            gd.setFullScreenWindow(null);
        }
    }

    public class MaxscreenAction implements ActionListener {
        JFrame mainframe;
        public MaxscreenAction(JFrame jframe) {
            this.mainframe = jframe;
        }

        @Override
        public void actionPerformed(ActionEvent evt) {
            // https://docs.oracle.com/javase/8/docs/api/java/awt/Toolkit.html#isFrameStateSupported-int-
            // https://docs.oracle.com/javase/8/docs/api/java/awt/Frame.html#getExtendedState-int-
            // https://docs.oracle.com/javase/8/docs/api/java/awt/Frame.html#setExtendedState-int-
            if (Toolkit.getDefaultToolkit().isFrameStateSupported(JFrame.MAXIMIZED_BOTH)) {
                int state = this.mainframe.getExtendedState();
                System.out.println("Window State: " + state);
                if (state == JFrame.MAXIMIZED_BOTH) {
                    this.mainframe.setExtendedState(JFrame.NORMAL);
                } else {
                    this.mainframe.setExtendedState(JFrame.MAXIMIZED_BOTH);
                }
                System.out.println("Window Size: " + this.mainframe.getSize());
            } else {
                System.out.println("System Not Support FrameState!");
            }
        }
    }

    public class FullscreenAction implements ActionListener {
        JFrame mainframe;
        public FullscreenAction(JFrame jframe) {
            this.mainframe = jframe;
        }

        @Override
        public void actionPerformed(ActionEvent evt) {
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            //通过调用 GraphicsEnvironment 的 getDefaultScreenDevice 方法获得当前的屏幕设备了
            GraphicsDevice gd = ge.getDefaultScreenDevice();
            // https://docs.oracle.com/javase/7/docs/api/java/awt/GraphicsDevice.html#getFullScreenWindow() 
            Window w = gd.getFullScreenWindow();
            if (w == this.mainframe) {
                // 退出全屏
                gd.setFullScreenWindow(null);
            } else {
                // 全屏显示
                gd.setFullScreenWindow(this.mainframe);
            }
        }
    }
}
